 package com.gametime.setup;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Random;

import com.gametime.model.AttributeSet;
import com.gametime.model.Person;
import com.gametime.model.Player;
import com.gametime.model.Position;
import com.gametime.model.Role;
import com.gametime.util.DBUtils;

public class AttributeGenerator {

	/**
	 * @param args
	 */
	private static AttributeGenerator instance =null;
	private final int MAX_VALUE_STARTER=10;
	private final int MAX_VALUE_ROTATION=8;
	private final int MAX_VALUE_RESERVE=6;
	private int maxValue=MAX_VALUE_RESERVE;
	private AttributeGenerator()
	{
		
	}
	
	public static AttributeGenerator getInstance()
	{
		if(instance == null)
			instance = new AttributeGenerator();
		return instance;
	}
	
	public AttributeSet getAttributes(Player p) throws Exception
	{
	  maxValue = figureMaxValue(p.getExperience(), p.getRole());
		AttributeSet attribs = new AttributeSet();
		attribs.setAgility(getRandomNumber());
		attribs.setCharisma(getRandomNumber());
		attribs.setDesire(getRandomNumber());
		attribs.setEgo(getRandomNumber());
		attribs.setEndurance(getRandomNumber());
		attribs.setEnergy(getRandomNumber());
		attribs.setHandle(getRandomNumber());
		attribs.setHealth(getRandomNumber());
		attribs.setIntelligence(getRandomNumber());
		attribs.setKarma(getRandomNumber());
		attribs.setPerson(getRandomNumber());
		attribs.setShotSelect(getRandomNumber());
		attribs.setShotSkill(getRandomNumber());
		attribs.setSize(getRandomNumber());
		attribs.setStrength(getRandomNumber());
		
		
		adjustAgility(attribs, p);
		adjustCharisma(attribs, p);
		adjustDesire(attribs, p);
		adjustEgo(attribs, p);
		adjustEndurance(attribs, p);
		adjustEnergy(attribs, p);
		adjustHandle(attribs, p);
		adjustPerson(attribs, p);
		adjustHealth(attribs, p);
		adjustIntelligence(attribs, p);
		adjustShotSelect(attribs, p);
		adjustShotSkill(attribs, p);
		adjustSize(attribs, p);
		adjustStrength(attribs, p);
		adjustKarma(attribs, p);
		return attribs;
	}
	
	

	private int figureMaxValue(int experience, String role)
  {
    // TODO Auto-generated method stub
	  if(role.equals(Role.STARTER))
	    return MAX_VALUE_STARTER;
	  if(experience > 9)
	    return MAX_VALUE_STARTER;
	  if(role.equals(Role.ROTATION))
      return MAX_VALUE_ROTATION;
    return MAX_VALUE_RESERVE;
  }

  private void adjustPerson(AttributeSet attribs, Player p) {
		if(p.getExperience() > 10)
			attribs.setPerson(attribs.getPerson() + 2);
		if(p.getExperience() > 7)
			attribs.setPerson(attribs.getPerson() + 1);
		
		if(p.getPosition().getPositionId() == 1)
		{
			attribs.setPerson(attribs.getPerson() + 1);
		}
		
	}

	private void adjustSize(AttributeSet attribs, Player p) throws Exception
	{
		// TODO Auto-generated method stub
		int size = getSizeNumber(p.getPerson());
		
		if(p.getExperience() > 9)
			size = size -1;
		
		attribs.setSize(size);
		
	}
	
	private void adjustStrength(AttributeSet attribs, Player p) {
		if(attribs.getSize() > 9)
		{
			attribs.setStrength((attribs.getStrength() + 2));
		}else if(attribs.getSize() > 6)
		{
			attribs.setStrength((attribs.getStrength() + 1));
		}else  if(attribs.getSize() < 2)
		{
			attribs.setStrength((attribs.getStrength() - 2));
		}else  if(attribs.getSize() < 4)
		{
			attribs.setStrength((attribs.getStrength() - 1));
		}
	}

	

	private void adjustShotSkill(AttributeSet attribs, Player p) {
		if(attribs.getKarma() > 9)
		{
			attribs.setShotSkill((attribs.getShotSkill() + 2));
		}else if(attribs.getKarma() > 6)
		{
			attribs.setShotSkill((attribs.getShotSkill() + 1));
		}else  if(attribs.getKarma() < 2)
		{
			attribs.setShotSkill((attribs.getShotSkill() - 2));
		}else  if(attribs.getKarma() < 4)
		{
			attribs.setShotSkill((attribs.getShotSkill() - 1));
		}
	}

	private void adjustShotSelect(AttributeSet attribs, Player p) {
		// TODO Auto-generated method stub
		if(p.getExperience() > 10)
			attribs.setShotSelect(attribs.getShotSelect() + 2);
		if(p.getExperience() > 7)
			attribs.setShotSelect(attribs.getShotSelect() + 1);
		
		
	}

	private void adjustKarma(AttributeSet attribs, Player p) {
		// TODO Auto-generated method stub
		if(p.getExperience() > 12)
			attribs.setKarma(attribs.getKarma() + 2);
		if(p.getExperience() > 10)
			attribs.setKarma(attribs.getKarma() + 1);
		
		if(p.getPosition().getPositionId() == 3 || p.getPosition().getPositionId() == 5)
		{
			attribs.setKarma(attribs.getKarma() + 1);
		}
		
	}

	private void adjustIntelligence(AttributeSet attribs, Player p) {
		// TODO Auto-generated method stub
		if(p.getExperience() > 13)
			attribs.setIntelligence(attribs.getIntelligence() + 3);
		else if(p.getExperience() > 10)
			attribs.setIntelligence(attribs.getIntelligence() + 2);
		if(p.getExperience() > 7)
			attribs.setIntelligence(attribs.getIntelligence() + 1);
		
		
		if(p.getPosition().getPositionId() == 1)
		{
			attribs.setIntelligence(attribs.getIntelligence() + 1);
		}
		
	
		
	}

	private void adjustEndurance(AttributeSet attribs, Player p) {
		
		if(p.getExperience() > 13)
			attribs.setEndurance(attribs.getEndurance() - 3);
		else if(p.getExperience() > 10)
			attribs.setEndurance(attribs.getEndurance() - 2);
		else if(p.getExperience() > 7)
			attribs.setEndurance(attribs.getEndurance() - 1);
		
		
	}
	
	private void adjustEnergy(AttributeSet attribs, Player p) {
    
    if(p.getExperience() > 13)
      attribs.setEndurance(attribs.getEndurance() - 3);
    else if(p.getExperience() > 10)
      attribs.setEndurance(attribs.getEndurance() - 2);
    else if(p.getExperience() > 7)
      attribs.setEndurance(attribs.getEndurance() - 1);
    
    
  }

	private void adjustHealth(AttributeSet attribs, Player p) {
		// TODO Auto-generated method stub
		if(p.getExperience() > 14)
			attribs.setHealth(attribs.getHealth() - 3);
		if(p.getExperience() > 10)
			attribs.setHealth(attribs.getHealth() - 2);
		if(p.getExperience() > 8)
			attribs.setHealth(attribs.getHealth() - 1);
		// high experience --
		
		if(attribs.getKarma() > 9)
		{
			attribs.setHealth((attribs.getHealth() + 2));
		}else if(attribs.getKarma() > 6)
		{
			attribs.setHealth((attribs.getHealth() + 1));
		}else  if(attribs.getKarma() < 2)
		{
			attribs.setHealth((attribs.getHealth() - 2));
		}else  if(attribs.getKarma() < 4)
		{
			attribs.setHealth((attribs.getHealth() - 1));
		}
		
	}

	private void adjustHandle(AttributeSet attribs, Player p) {
		// TODO Auto-generated method stub
		// point guard ++
		if(p.getPosition().getPositionId() == 1)
		{
			attribs.setHandle(attribs.getHandle() + 3);
		} else if(p.getPosition().getPositionId() == 2)
		{
			attribs.setHandle(attribs.getHandle() + 2);
		} else if(p.getPosition().getPositionId() == 3)
		{
			attribs.setHandle(attribs.getHandle() + 1);
		} else if(p.getPosition().getPositionId() == 9)
		{
			attribs.setHandle(attribs.getHandle() -2);
		}else if(p.getPosition().getPositionId() > 6)
		{
			attribs.setHandle(attribs.getHandle() -1);
		}  
		
	}

	private void adjustEgo(AttributeSet attribs, Player p) {
		// TODO Auto-generated method stub
		// high experience --
		if(p.getExperience() > 9)
		{
			attribs.setEgo(attribs.getEgo() + 1);
		}
		// point guard --
		if(p.getPosition().getPositionId() == 1)
		{
			attribs.setEgo(attribs.getEgo() - 1);
		}
	}

	private void adjustDesire(AttributeSet attribs, Player p) {
		// high experience will have a positive effect
		if(p.getExperience() > 9)
		{
			attribs.setDesire(attribs.getDesire() + 1);
		}
		
	}

	private void adjustCharisma(AttributeSet attribs, Player p) {
		// high experience will have a positive effect
		// PG ++
		if(p.getPosition().getPositionId() == 1)
		{
			attribs.setCharisma(attribs.getCharisma() + 1);
		}
		
		if(p.getExperience() > 9)
		{
			attribs.setCharisma(attribs.getCharisma() + 1);
		}
		
	}
	private void adjustAgility(AttributeSet attribs, Player p) {
		// TODO Auto-generated method stub
		// small forward, wing, bg ++ 
		if(p.getPosition().getPositionId() < 5)
			attribs.setAgility(( attribs.getAgility() + 1));
		else if(p.getPosition().getPositionId() >= 8) {
			attribs.setAgility(( attribs.getAgility() - 1));
		}
		// center, center forward --
		
		// low health will have a negative affect
		
		// high experience will have a negative effect
		
		
		
	}

	private int getRandomNumber()
	{
		Random r = new Random();	
		return r.nextInt(maxValue - 1 + 1) + 1;
	}
	
	private int getSizeNumber(Person person) throws Exception
	{
		int result=0;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		final String sql =
				"select value from gen_size where height = ? and ? between weight_min and weight_max";
		try
		{
			conn = DBUtils.getInstance().getConnection();
			ps = conn.prepareStatement(sql);
			ps.setInt(1, person.getHeight());
			ps.setInt(2, person.getWeight());
			rs = ps.executeQuery();
			while(rs.next())
			{
				result = rs.getInt(1);
			}
			
		}catch(Exception e)
		{	
			e.printStackTrace();
			throw e;
		}finally
		{
			rs.close();
			ps.close();
			DBUtils.closeConnection(conn);
		}
		return result;
	}

}
